/*! touchjs.min v0.2.14  2014-08-05 */
"use strict";
!function (a, b) {
    "function" == typeof define && (define.amd || define.cmd) ? define(b) : a.touch = b()
}(this, function () {
    function a() {
        var a = "mouseup mousedown mousemove mouseout", c = "touchstart touchmove touchend touchcancel", d = b.hasTouch ? c : a;
        d.split(" ").forEach(function (a) {
            document.addEventListener(a, A, !1)
        })
    }

    var b = {};
    b.PCevts = {touchstart: "mousedown", touchmove: "mousemove", touchend: "mouseup", touchcancel: "mouseout"}, b.hasTouch = "ontouchstart" in window, b.getType = function (a) {
        return Object.prototype.toString.call(a).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()
    }, b.getSelector = function (a) {
        if (a.id)return "#" + a.id;
        if (a.className) {
            var b = a.className.split(/\s+/);
            return "." + b.join(".")
        }
        return a === document ? "body" : a.tagName.toLowerCase()
    }, b.matchSelector = function (a, b) {
        return a.webkitMatchesSelector(b)
    }, b.getEventListeners = function (a) {
        return a.listeners
    }, b.getPCevts = function (a) {
        return this.PCevts[a] || a
    }, b.forceReflow = function () {
        var a = "reflowDivBlock", b = document.getElementById(a);
        b || (b = document.createElement("div"), b.id = a, document.body.appendChild(b));
        var c = b.parentNode, d = b.nextSibling;
        c.removeChild(b), c.insertBefore(b, d)
    }, b.simpleClone = function (a) {
        return Object.create(a)
    }, b.getPosOfEvent = function (a) {
        if (this.hasTouch) {
            for (var b = [], c = null, d = 0, e = a.touches.length; e > d; d++)c = a.touches[d], b.push({x: c.pageX, y: c.pageY});
            return b
        }
        return [{x: a.pageX, y: a.pageY}]
    }, b.getDistance = function (a, b) {
        var c = b.x - a.x, d = b.y - a.y;
        return Math.sqrt(c * c + d * d)
    }, b.getFingers = function (a) {
        return a.touches ? a.touches.length : 1
    }, b.calScale = function (a, b) {
        if (a.length >= 2 && b.length >= 2) {
            var c = this.getDistance(a[1], a[0]), d = this.getDistance(b[1], b[0]);
            return d / c
        }
        return 1
    }, b.getAngle = function (a, b) {
        return 180 * Math.atan2(b.y - a.y, b.x - a.x) / Math.PI
    }, b.getAngle180 = function (a, b) {
        var c = Math.atan(-1 * (b.y - a.y) / (b.x - a.x)) * (180 / Math.PI);
        return 0 > c ? c + 180 : c
    }, b.getDirectionFromAngle = function (a) {
        var b = {up: -45 > a && a > -135, down: a >= 45 && 135 > a, left: a >= 135 || -135 >= a, right: a >= -45 && 45 >= a};
        for (var c in b)if (b[c])return c;
        return null
    }, b.getXYByElement = function (a) {
        for (var b = 0, c = 0; a.offsetParent;)b += a.offsetLeft, c += a.offsetTop, a = a.offsetParent;
        return {left: b, top: c}
    }, b.reset = function () {
        h = i = j = null, q = o = k = l = !1, m = !1, f = {}, t = !1
    }, b.isTouchMove = function (a) {
        return "touchmove" === a.type || "mousemove" === a.type
    }, b.isTouchEnd = function (a) {
        return "touchend" === a.type || "mouseup" === a.type || "touchcancel" === a.type
    }, b.env = function () {
        var a = {}, b = navigator.userAgent, c = b.match(/(Android)[\s\/]+([\d\.]+)/), d = b.match(/(iPad|iPhone|iPod)\s+OS\s([\d_\.]+)/), e = b.match(/(Windows\s+Phone)\s([\d\.]+)/), f = /WebKit\/[\d.]+/i.test(b), g = d ? navigator.standalone ? f : /Safari/i.test(b) && !/CriOS/i.test(b) && !/MQQBrowser/i.test(b) : !1;
        return c && (a.android = !0, a.version = c[2]), d && (a.ios = !0, a.version = d[2].replace(/_/g, "."), a.ios7 = /^7/.test(a.version), "iPad" === d[1] ? a.ipad = !0 : "iPhone" === d[1] ? (a.iphone = !0, a.iphone5 = 568 == screen.height) : "iPod" === d[1] && (a.ipod = !0)), e && (a.wp = !0, a.version = e[2], a.wp8 = /^8/.test(a.version)), f && (a.webkit = !0), g && (a.safari = !0), a
    }();
    var c = {
        proxyid: 0, proxies: [], trigger: function (a, b, c) {
            c = c || {};
            var d, e = {bubbles: !0, cancelable: !0, detail: c};
            try {
                "undefined" != typeof CustomEvent ? (d = new CustomEvent(b, e), a && a.dispatchEvent(d)) : (d = document.createEvent("CustomEvent"), d.initCustomEvent(b, !0, !0, c), a && a.dispatchEvent(d))
            } catch (f) {
                console.warn("Touch.js is not supported by environment.")
            }
        }, bind: function (a, c, d) {
            a.listeners = a.listeners || {}, a.listeners[c] ? a.listeners[c].push(d) : a.listeners[c] = [d];
            var e = function (a) {
                b.env.ios7 && b.forceReflow(), a.originEvent = a;
                for (var c in a.detail)"type" !== c && (a[c] = a.detail[c]);
                a.startRotate = function () {
                    t = !0
                };
                var e = d.call(a.target, a);
                "undefined" == typeof e || e || (a.stopPropagation(), a.preventDefault())
            };
            d.proxy = d.proxy || {}, d.proxy[c] ? d.proxy[c].push(this.proxyid++) : d.proxy[c] = [this.proxyid++], this.proxies.push(e), a.addEventListener && a.addEventListener(c, e, !1)
        }, unbind: function (a, b, c) {
            if (c) {
                var d = c.proxy[b];
                d && d.length && d.forEach(function () {
                    a.removeEventListener && a.removeEventListener(b, this.proxies[this.proxyid], !1)
                })
            } else {
                var e = a.listeners[b];
                e && e.length && e.forEach(function (c) {
                    a.removeEventListener(b, c, !1)
                })
            }
        }, delegate: function (a, c, d, e) {
            var f = function (c) {
                var f, g;
                c.originEvent = c;
                for (var h in c.detail)"type" !== h && (c[h] = c.detail[h]);
                c.startRotate = function () {
                    t = !0
                };
                var i = b.getSelector(a) + " " + d, j = b.matchSelector(c.target, i), k = b.matchSelector(c.target, i + " " + c.target.nodeName);
                if (!j && k) {
                    for (b.env.ios7 && b.forceReflow(), f = c.target; !b.matchSelector(f, i);)f = f.parentNode;
                    g = e.call(c.target, c), "undefined" == typeof g || g || (c.stopPropagation(), c.preventDefault())
                } else b.env.ios7 && b.forceReflow(), (j || k) && (g = e.call(c.target, c), "undefined" == typeof g || g || (c.stopPropagation(), c.preventDefault()))
            };
            e.proxy = e.proxy || {}, e.proxy[c] ? e.proxy[c].push(this.proxyid++) : e.proxy[c] = [this.proxyid++], this.proxies.push(f), a.listeners = a.listeners || {}, a.listeners[c] ? a.listeners[c].push(f) : a.listeners[c] = [f], a.addEventListener && a.addEventListener(c, f, !1)
        }, undelegate: function (a, b, c, d) {
            if (d) {
                var e = d.proxy[b];
                e.length && e.forEach(function () {
                    a.removeEventListener && a.removeEventListener(b, this.proxies[this.proxyid], !1)
                })
            } else {
                var f = a.listeners[b];
                f.forEach(function (c) {
                    a.removeEventListener(b, c, !1)
                })
            }
        }
    }, d = {tap: !0, doubleTap: !0, tapMaxDistance: 10, hold: !0, tapTime: 200, holdTime: 650, maxDoubleTapInterval: 300, swipe: !0, swipeTime: 300, swipeMinDistance: 18, swipeFactor: 5, drag: !0, pinch: !0, minScaleRate: 0, minRotationAngle: 0}, e = {TOUCH_START: "touchstart", TOUCH_MOVE: "touchmove", TOUCH_END: "touchend", TOUCH_CANCEL: "touchcancel", MOUSE_DOWN: "mousedown", MOUSE_MOVE: "mousemove", MOUSE_UP: "mouseup", CLICK: "click", PINCH_START: "pinchstart", PINCH_END: "pinchend", PINCH: "pinch", PINCH_IN: "pinchin", PINCH_OUT: "pinchout", ROTATION_LEFT: "rotateleft", ROTATION_RIGHT: "rotateright", ROTATION: "rotate", SWIPE_START: "swipestart", SWIPING: "swiping", SWIPE_END: "swipeend", SWIPE_LEFT: "swipeleft", SWIPE_RIGHT: "swiperight", SWIPE_UP: "swipeup", SWIPE_DOWN: "swipedown", SWIPE: "swipe", DRAG: "drag", DRAGSTART: "dragstart", DRAGEND: "dragend", HOLD: "hold", TAP: "tap", DOUBLE_TAP: "doubletap"}, f = {
        start: null,
        move: null,
        end: null
    }, g = 0, h = null, i = null, j = null, k = !1, l = !1, m = !1, n = {}, o = !1, p = null, q = !1, r = null, s = 1, t = !1, u = [], v = 0, w = 0, x = 0, y = null, z = {
        getAngleDiff: function (a) {
            for (var c = parseInt(v - b.getAngle180(a[0], a[1]), 10), d = 0; Math.abs(c - w) > 90 && d++ < 50;)0 > w ? c -= 180 : c += 180;
            return w = parseInt(c, 10)
        }, pinch: function (a) {
            var g = a.target;
            if (d.pinch) {
                if (!o)return;
                if (b.getFingers(a) < 2 && !b.isTouchEnd(a))return;
                var h = b.calScale(f.start, f.move), i = this.getAngleDiff(f.move), j = {type: "", originEvent: a, scale: h, rotation: i, direction: i > 0 ? "right" : "left", fingersCount: b.getFingers(a)};
                if (l ? b.isTouchMove(a) ? (j.fingerStatus = "move", c.trigger(g, e.PINCH, j)) : b.isTouchEnd(a) && (j.fingerStatus = "end", c.trigger(g, e.PINCH_END, j), b.reset()) : (l = !0, j.fingerStatus = "start", c.trigger(g, e.PINCH_START, j)), Math.abs(1 - h) > d.minScaleRate) {
                    var k = b.simpleClone(j), m = 1e-11;
                    h > s ? (s = h - m, c.trigger(g, e.PINCH_OUT, k, !1)) : s > h && (s = h + m, c.trigger(g, e.PINCH_IN, k, !1)), b.isTouchEnd(a) && (s = 1)
                }
                if (Math.abs(i) > d.minRotationAngle) {
                    var n, p = b.simpleClone(j);
                    n = i > 0 ? e.ROTATION_RIGHT : e.ROTATION_LEFT, c.trigger(g, n, p, !1), c.trigger(g, e.ROTATION, j)
                }
            }
        }, rotateSingleFinger: function (a) {
            var d = a.target;
            if (t && b.getFingers(a) < 2) {
                if (!f.move)return;
                if (u.length < 2) {
                    var g = b.getXYByElement(d);
                    u = [{x: g.left + d.offsetWidth / 2, y: g.top + d.offsetHeight / 2}, f.move[0]], v = parseInt(b.getAngle180(u[0], u[1]), 10)
                }
                var h = [u[0], f.move[0]], i = this.getAngleDiff(h), j = {type: "", originEvent: a, rotation: i, direction: i > 0 ? "right" : "left", fingersCount: b.getFingers(a)};
                b.isTouchMove(a) ? j.fingerStatus = "move" : (b.isTouchEnd(a) || "mouseout" === a.type) && (j.fingerStatus = "end", c.trigger(d, e.PINCH_END, j), b.reset());
                var k = i > 0 ? e.ROTATION_RIGHT : e.ROTATION_LEFT;
                c.trigger(d, k, j), c.trigger(d, e.ROTATION, j)
            }
        }, swipe: function (a) {
            var h = a.target;
            if (o && f.move && !(b.getFingers(a) > 1)) {
                var i = Date.now(), j = i - g, l = b.getDistance(f.start[0], f.move[0]), p = {x: f.move[0].x - n.left, y: f.move[0].y - n.top}, q = b.getAngle(f.start[0], f.move[0]), r = b.getDirectionFromAngle(q), s = j / 1e3, t = 10 * (10 - d.swipeFactor) * s * s, u = {type: e.SWIPE, originEvent: a, position: p, direction: r, distance: l, distanceX: f.move[0].x - f.start[0].x, distanceY: f.move[0].y - f.start[0].y, x: f.move[0].x - f.start[0].x, y: f.move[0].y - f.start[0].y, angle: q, duration: j, fingersCount: b.getFingers(a), factor: t};
                if (d.swipe) {
                    var v = function () {
                        var a = e;
                        switch (r) {
                            case"up":
                                c.trigger(h, a.SWIPE_UP, u);
                                break;
                            case"down":
                                c.trigger(h, a.SWIPE_DOWN, u);
                                break;
                            case"left":
                                c.trigger(h, a.SWIPE_LEFT, u);
                                break;
                            case"right":
                                c.trigger(h, a.SWIPE_RIGHT, u)
                        }
                    };
                    k ? b.isTouchMove(a) ? (u.fingerStatus = u.swipe = "move", c.trigger(h, e.SWIPING, u), j > d.swipeTime && j < d.swipeTime + 50 && l > d.swipeMinDistance && (v(), c.trigger(h, e.SWIPE, u, !1))) : (b.isTouchEnd(a) || "mouseout" === a.type) && (u.fingerStatus = u.swipe = "end", c.trigger(h, e.SWIPE_END, u), d.swipeTime > j && l > d.swipeMinDistance && (v(), c.trigger(h, e.SWIPE, u, !1))) : (u.fingerStatus = u.swipe = "start", k = !0, c.trigger(h, e.SWIPE_START, u))
                }
                d.drag && (m ? b.isTouchMove(a) ? (u.fingerStatus = u.swipe = "move", c.trigger(h, e.DRAG, u)) : b.isTouchEnd(a) && (u.fingerStatus = u.swipe = "end", c.trigger(h, e.DRAGEND, u)) : (u.fingerStatus = u.swipe = "start", m = !0, c.trigger(h, e.DRAGSTART, u)))
            }
        }, tap: function (a) {
            var h = a.target;
            if (d.tap) {
                var i = Date.now(), j = i - g, k = b.getDistance(f.start[0], f.move ? f.move[0] : f.start[0]);
                clearTimeout(p);
                var l = function () {
                    if (y && d.doubleTap && g - x < d.maxDoubleTapInterval) {
                        var a = b.getDistance(y, f.start[0]);
                        if (16 > a)return !0
                    }
                    return !1
                }();
                if (l)return clearTimeout(r), void c.trigger(h, e.DOUBLE_TAP, {type: e.DOUBLE_TAP, originEvent: a, position: f.start[0]});
                if (d.tapMaxDistance < k)return;
                d.holdTime > j && b.getFingers(a) <= 1 && (q = !0, x = i, y = f.start[0], r = setTimeout(function () {
                    c.trigger(h, e.TAP, {type: e.TAP, originEvent: a, fingersCount: b.getFingers(a), position: y})
                }, d.tapTime))
            }
        }, hold: function (a) {
            var e = a.target;
            d.hold && (clearTimeout(p), p = setTimeout(function () {
                if (f.start) {
                    var g = b.getDistance(f.start[0], f.move ? f.move[0] : f.start[0]);
                    d.tapMaxDistance < g || q || c.trigger(e, "hold", {type: "hold", originEvent: a, fingersCount: b.getFingers(a), position: f.start[0]})
                }
            }, d.holdTime))
        }
    }, A = function (a) {
        var c = a.target;
        switch (a.type) {
            case"touchstart":
            case"mousedown":
                u = [], o = !0, (!f.start || f.start.length < 2) && (f.start = b.getPosOfEvent(a)), b.getFingers(a) >= 2 && (v = parseInt(b.getAngle180(f.start[0], f.start[1]), 10)), g = Date.now(), h = a, n = {};
                var d = c.getBoundingClientRect(), e = document.documentElement;
                n = {top: d.top + (window.pageYOffset || e.scrollTop) - (e.clientTop || 0), left: d.left + (window.pageXOffset || e.scrollLeft) - (e.clientLeft || 0)}, z.hold(a);
                break;
            case"touchmove":
            case"mousemove":
                if (!o || !f.start)return;
                f.move = b.getPosOfEvent(a), b.getFingers(a) >= 2 ? z.pinch(a) : t ? z.rotateSingleFinger(a) : z.swipe(a);
                break;
            case"touchend":
            case"touchcancel":
            case"mouseup":
            case"mouseout":
                if (!o)return;
                j = a, l ? z.pinch(a) : t ? z.rotateSingleFinger(a) : k ? z.swipe(a) : z.tap(a), b.reset(), v = 0, w = 0, a.touches && 1 === a.touches.length && (o = !0, t = !0)
        }
    }, B = function () {
        function a(a) {
            b.hasTouch || (a = b.getPCevts(a)), j.forEach(function (b) {
                c.delegate(b, a, h, g[a])
            })
        }

        function d(a) {
            b.hasTouch || (a = b.getPCevts(a)), j.forEach(function (b) {
                c.bind(b, a, g[a])
            })
        }

        var e, f, g, h, i = arguments;
        if (i.length < 2 || i > 4)return console.error("unexpected arguments!");
        var j = "string" === b.getType(i[0]) ? document.querySelectorAll(i[0]) : i[0];
        if (j = j.length ? Array.prototype.slice.call(j) : [j], 3 === i.length && "string" === b.getType(i[1]))return e = i[1].split(" "), f = i[2], void e.forEach(function (a) {
            b.hasTouch || (a = b.getPCevts(a)), j.forEach(function (b) {
                c.bind(b, a, f)
            })
        });
        if (3 !== i.length || "object" !== b.getType(i[1]))if (2 !== i.length || "object" !== b.getType(i[1])) {
            if (4 === i.length && "object" === b.getType(i[2]))return e = i[1].split(" "), f = i[3], void e.forEach(function (a) {
                b.hasTouch || (a = b.getPCevts(a)), j.forEach(function (b) {
                    c.bind(b, a, f)
                })
            });
            if (4 === i.length) {
                var k = j[0];
                return e = i[1].split(" "), h = i[2], f = i[3], void e.forEach(function (a) {
                    b.hasTouch || (a = b.getPCevts(a)), c.delegate(k, a, h, f)
                })
            }
        } else {
            g = i[1];
            for (var l in g)d(l)
        } else {
            g = i[1], h = i[2];
            for (var m in g)a(m)
        }
    }, C = function () {
        var a, d, e = arguments;
        if (e.length < 1 || e.length > 4)return console.error("unexpected arguments!");
        var f = "string" === b.getType(e[0]) ? document.querySelectorAll(e[0]) : e[0];
        if (f = f.length ? Array.prototype.slice.call(f) : [f], 1 === e.length || 2 === e.length)return void f.forEach(function (d) {
            a = e[1] ? e[1].split(" ") : Object.keys(d.listeners), a.length && a.forEach(function (a) {
                b.hasTouch || (a = b.getPCevts(a)), c.unbind(d, a), c.undelegate(d, a)
            })
        });
        if (3 === e.length && "function" === b.getType(e[2]))return d = e[2], void f.forEach(function (f) {
            a = e[1].split(" "), a.forEach(function (a) {
                b.hasTouch || (a = b.getPCevts(a)), c.unbind(f, a, d)
            })
        });
        if (3 === e.length && "string" === b.getType(e[2])) {
            var g = e[2];
            return void f.forEach(function (d) {
                a = e[1].split(" "), a.forEach(function (a) {
                    b.hasTouch || (a = b.getPCevts(a)), c.undelegate(d, a, g)
                })
            })
        }
        return 4 === e.length ? (d = e[3], void f.forEach(function (f) {
            a = e[1].split(" "), a.forEach(function (a) {
                b.hasTouch || (a = b.getPCevts(a)), c.undelegate(f, a, g, d)
            })
        })) : void 0
    }, D = function (a, d, e) {
        var f = arguments;
        b.hasTouch || (d = b.getPCevts(d));
        var g = "string" === b.getType(f[0]) ? document.querySelectorAll(f[0]) : f[0];
        g = g.length ? Array.prototype.call(g) : [g], g.forEach(function (a) {
            c.trigger(a, d, e)
        })
    };
    a();
    var E = {};
    return E.on = E.bind = E.live = B, E.off = E.unbind = E.die = C, E.config = d, E.trigger = D, E
});